package cn.chiship.sdk.third.other;

import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.encryption.AesUtil;
import cn.chiship.sdk.core.exception.ExceptionUtil;
import cn.chiship.sdk.core.exception.custom.SystemErrorException;
import cn.chiship.sdk.core.util.PrintUtil;
import cn.chiship.sdk.core.util.PropertiesFileUtil;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.sdk.third.core.common.ThirdConstants;
import cn.chiship.sdk.third.core.model.EmailConfigModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.MissingResourceException;
import java.util.Properties;

/**
 * <p>
 * 发送邮件工具类
 * </p>
 * Created by lj on 2017-10-17.
 *
 * @author lj
 */
public class EmailClient {

    private static final Logger LOGGER = LoggerFactory.getLogger(EmailClient.class);

    private EmailConfigModel emailConfigModel;

    private static EmailClient instance;

    private EmailClient() {
    }

    public static synchronized EmailClient getInstance() {
        if (instance == null) {
            instance = new EmailClient();
        }
        return instance;
    }

    public EmailClient config() {
        try {
            this.emailConfigModel = new EmailConfigModel(
                    PropertiesFileUtil.getInstance(ThirdConstants.PROPERTIES_FILE_NAME).get("EMAIL_CONFIG_HOST"),
                    PropertiesFileUtil.getInstance(ThirdConstants.PROPERTIES_FILE_NAME)
                            .get("EMAIL_CONFIG_TRANSPORT_PROTOCOL"),
                    PropertiesFileUtil.getInstance(ThirdConstants.PROPERTIES_FILE_NAME)
                            .getBool("EMAIL_CONFIG_SMTP_AUTH"),
                    PropertiesFileUtil.getInstance(ThirdConstants.PROPERTIES_FILE_NAME).get("EMAIL_CONFIG_SMTP_PORT"),
                    PropertiesFileUtil.getInstance(ThirdConstants.PROPERTIES_FILE_NAME).getBool("EMAIL_CONFIG_IS_SSL"),
                    PropertiesFileUtil.getInstance(ThirdConstants.PROPERTIES_FILE_NAME)
                            .get("EMAIL_CONFIG_SMTP_SSL_PORT"),
                    PropertiesFileUtil.getInstance(ThirdConstants.PROPERTIES_FILE_NAME)
                            .get("EMAIL_CONFIG_SEND_ADDRESS"),
                    PropertiesFileUtil.getInstance(ThirdConstants.PROPERTIES_FILE_NAME)
                            .get("EMAIL_CONFIG_SEND_ADDRESS_PASSWORD"));
            if (StringUtil.isNullOrEmpty(emailConfigModel.getMailHost())
                    || StringUtil.isNullOrEmpty(emailConfigModel.getMailTransportProtocol())
                    || StringUtil.isNullOrEmpty(emailConfigModel.getMailSmtpAuth().toString())
                    || StringUtil.isNullOrEmpty(emailConfigModel.getMailSmtpPort())
                    || StringUtil.isNullOrEmpty(emailConfigModel.getMailIsSsl().toString())
                    || StringUtil.isNullOrEmpty(emailConfigModel.getMailSmtpSslPort())
                    || StringUtil.isNullOrEmpty(emailConfigModel.getMailSendFromAddress())
                    || StringUtil.isNullOrEmpty(AesUtil.aesDecode(emailConfigModel.getMailSendFromAddressPassword()))) {
                throw new SystemErrorException("兄弟,请确保邮箱的各个属性配置存在或值不为空!");
            }
        } catch (MissingResourceException e) {
            throw new SystemErrorException(ThirdConstants.ERROR_EXIST_TIP_1);
        }
        return this;
    }

    public EmailClient config(EmailConfigModel emailConfigModel) {
        this.emailConfigModel = emailConfigModel;
        this.emailConfigModel
                .setMailSendFromAddressPassword(AesUtil.aesDecode(emailConfigModel.getMailSendFromAddressPassword()));
        return this;
    }

    private Session getSendEmailSession() {
        Properties prop = new Properties();
        prop.setProperty("mail.host", emailConfigModel.getMailHost());
        prop.setProperty("mail.transport.protocol", emailConfigModel.getMailTransportProtocol());
        prop.setProperty("mail.smtp.auth", String.valueOf(emailConfigModel.getMailSmtpAuth()));
        if (Boolean.TRUE.equals(emailConfigModel.getMailIsSsl())) {
            prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            prop.put("mail.smtp.socketFactory.port", emailConfigModel.getMailSmtpSslPort());
            prop.put("mail.smtp.port", emailConfigModel.getMailSmtpPort());
            prop.put("mail.smtp.ssl.checkserveridentity", true);
        } else {
            prop.setProperty("mail.smtp.port", emailConfigModel.getMailSmtpPort());
        }

        Session session = Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(emailConfigModel.getMailSendFromAddress(),
                        emailConfigModel.getMailSendFromAddressPassword());
            }
        });
        session.setDebug(true);

        return session;
    }

    public BaseResult sendText(String toAddress, String subject, String content) {
        try {
            Session session = getSendEmailSession();
            Transport ts = session.getTransport();
            ts.connect(emailConfigModel.getMailHost(), emailConfigModel.getMailSendFromAddress(),
                    emailConfigModel.getMailSendFromAddressPassword());
            Message message = createSimpleMail(session, toAddress, subject, content);
            ts.sendMessage(message, message.getAllRecipients());
            ts.close();
            LOGGER.info("--------------------发送邮件成功--------------------------");
            return BaseResult.ok(null);
        } catch (Exception e) {
            LOGGER.error("--------------------发送邮件错误--------------------------");
            LOGGER.error("发生异常", e);
            return ExceptionUtil.formatException(e);
        }
    }

    private MimeMessage createSimpleMail(Session session, String toAddress, String subject, String content)
            throws Exception {
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(emailConfigModel.getMailSendFromAddress()));
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
        message.setSubject(subject);
        message.setContent(content, "text/html;charset=UTF-8");
        return message;
    }

    public static void main(String[] args) {
        PrintUtil.console(AesUtil.aesEncode("BA11C4B21AE2684B"));
        EmailClient emailClient = EmailClient.getInstance().config();
        BaseResult baseResult = emailClient.sendText("alfred@titifootball.com", "2017.11.10意见反馈收集",
                "<p>10意见反馈收集</p><span style='color:red'>10意见反馈收集</span>");
        PrintUtil.console(baseResult);
    }

}
